import RenderContext from "@/views/cg/lib/RenderContext.ts";
import {identity3d, identity4d, multiply4} from "@/views/cg/lib/matrix";
import {ImageTexture} from "@/views/cg/lib/model/ImageTexture.ts";

export class Model {
  constructor(mesh, dimensions = 3,level=1) {
    this.mesh = mesh
    // 世界矩阵
    this.worldMatrix = dimensions === 3? identity4d() : identity3d()
    // 模型自己的矩阵
    this.unitMatrix = dimensions === 3? identity4d() : identity3d()
    this.gl = RenderContext.getGL()
    this.program = RenderContext.getProgram()
    this.gl.useProgram(this.program)
    // 共享世界矩阵
    this.children = []
    this.level = level
  }

  setVectorUniform(name, value) {
    const position = this.gl.getUniformLocation(this.program,name)
    if(value.length == 2){
      this.gl.uniform2fv(position, value)
    }else if(value.length == 3){
      this.gl.uniform3fv(position, value)
    } else if (value.length == 4){
      this.gl.uniform4fv(position, value)
    }
  }

  setMatrixUniform(name, value) {
    const position = this.gl.getUniformLocation(this.program,name)
    if(value.length == 4){
      this.gl.uniformMatrix2fv(position, false , value)
    }else if(value.length == 9){
      this.gl.uniformMatrix3fv(position, false , value)
    } else if (value.length == 16){
      this.gl.uniformMatrix4fv(position, false , value)
    }
  }

  setUnitMatrix(unitMatrix){
    this.unitMatrix = unitMatrix
  }


  //   通过 updateMatrix 替代递归  06-3d-rotate-model用
  setWorldMatrix06(worldMatrix){
    this.worldMatrix = worldMatrix
    // 每次设置worldMatrix ，让children也会收到。
    // 世界旋转 所有的都要旋转
    this.children.forEach(child => {
      child.setWorldMatrix(worldMatrix)
    })
  }

  setWorldMatrix(worldMatrix){
    this.worldMatrix = worldMatrix
  }

  // 递归新世界矩阵
  updateMatrix(parentWorldMatrix, parentUnitMatrix){
    // console.log(parentWorldMatrix, parentUnitMatrix)
    if(parentUnitMatrix){
      // 自己的世界矩阵
      // 顺序 pworld * punit * unit * vec4点
      // 但是为什么是 因为glsl 所有矩阵式转置过得  A(T) * B(T) = BA(T)
      this.worldMatrix = multiply4(parentUnitMatrix, parentWorldMatrix)
    }
    for(let child of this.children){
      child.updateMatrix(
        this.worldMatrix, this.unitMatrix
      )
    }
  }


  addChild(model){
    // 形成父子的关系链
    model.parent = this
    this.children.push(model)
  }

  // 增加纹理图片
  addTextureImage(src){
    this.textureImage = new ImageTexture(src)
  }

  draw(){
    if(this.unitMatrix){
      this.setMatrixUniform('u_unit',this.unitMatrix)
    }
    if(this.worldMatrix){
      this.setMatrixUniform('u_world',this.worldMatrix)
    }
    // if(this.un){
    //   this.setMatrixUniform('u_matrix',multiply4(this.unitMatrix))
    // }

    // 从demo5 开始 移到外面
    // const gl = this.gl;
    // gl.enable(gl.DEPTH_TEST)
    // gl.depthFunc(gl.LEQUAL)
    // gl.clearDepth(1.0)

    // gl.viewport(0,0, gl.canvas.width, gl.canvas.height)
    // gl.clear(gl.COLOR_BUFFER_BIT)
    if(this.mesh){
      this.textureImage && this.textureImage.associate()
      this.mesh.draw()
    }

    this.children.forEach(child => {
      child.draw()
    })
  }

  enableAttribute(name){
    if(this.mesh){
      this.mesh.enableAttribute(name)
    }
    this.children.forEach(child => {
      child.enableAttribute(name)
    })
  }
}
